package fr.gla.hibtracker.historique.bm;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

/**
 * <p>
 * Classe regroupant l'ensemble des modifications effectuées sur un objet lors d'un flush d'une session factory
 * hibernate.
 * </p>
 * <p>
 * Une instance de <code>GroupeModifications</code> encapsule <em>n</em> instances de {@link Modification} qui sont les
 * modifications pour chaque champ de l'objet (ancienne et nouvelle valeur).
 * </p>
 * <p>
 * Une instance de <code>GroupeModifications</code> encapsule également une
 * référence vers l'entité ayant été modifiée.
 * </p>
 * <p>
 * Attention ! Le mapping pour la reference vers l'entité stockée (<code>object</code>)
 * doit être précisé par l'application cliente.
 * </p>
 *
 * @param <T> Type de l'entité encapsulée.
 *
 * @see FlushModifications
 */
public class GroupeModifications<T> {

    private Integer            id;

    private T                  object;

    private Set<Modification>  modifications = new HashSet<Modification>();

    /**
     * Reference sur l'entitée contenante (relation bidirectionnelle).
     */
    private FlushModifications flushModifications;


    /**
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("object = " + object + "\n");
        for (Modification modification : getModifications()) {
            builder.append(modification + "\n");
        }
        return builder.toString();
    }

    /**
     * Ajoute la modification donnée au groupe de modifications.
     * @param modification Modification à ajouter.
     */
    public boolean addModification(Modification modification) {
        modification.getModificationID().setGroupeModifications(this);
        return modifications.add(modification);
    }

    /**
     * Ajoute toutes les modifications de <code>modificationsToAdd</code> aux modifications du gorupe.
     */
    public boolean addAllModification(Collection<Modification> modificationsToAdd) {
        return modificationsToAdd.addAll(modificationsToAdd);
    }

    public T getObject() {
        return object;
    }

    public void setObject(T object) {
        this.object = object;
    }

    public Set<Modification> getModifications() {
        return modifications;
    }

    public void setModifications(Set<Modification> modifications) {
        this.modifications = modifications;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public void setFlushModifications(FlushModifications flushModifications) {
        this.flushModifications = flushModifications;
    }

    public FlushModifications getFlushModifications() {
        return flushModifications;
    }
}
